<?php
namespace app\admin\middleware;

use app\common\model\Administrator;
use bigDream\thinkJump\Jump;
use think\Container;
use think\facade\Cookie;
use think\facade\Session;

/**
 * 登录验证中间件
 * @package app\admin\middleware
 * @author jwj<jwjbjg@gmail.com>
 * @copyright jwj
 */
class CheckLogin
{
    /**
     * @var \think\Request
     */
    protected $request;

    /**
     * Cookie|Session中的Token参数名
     * @var string
     */
    const TokenName = 'admin_token';

    /**
     * @param \think\Request $request
     * @param \Closure $next
     * @return mixed|\think\Response
     */
    public function handle($request, \Closure $next)
    {
        $this->request = $request;

        // 获取登录凭证
        $auth = $this->getAuthToken();


        // 判断是否已有登录凭证
        if (false !== $auth) {
            // 获取用户信息
            $user = Administrator::where('id', $auth[0])->where('token', $auth[1])->find();
            if (null === $user) {
                $this->jumpLogin('登录已失效，请重新登录');
            }

            // 用户状态
            if (1 != $user['status']) {
                $user->log()->save([
                    'info' => '用户状态异常，自动注销登录',
                    'extra' => 'logout',
                ]);

                $this->jumpLogin('用户状态异常，请联系管理员');
            }

            if (substr($user['active_time'], 0, -3) != date('Y-m-d H:i')) {
                // 更新最后活动时间
                $user->save(['active_time' => date('Y-m-d H:i:s')]);
            }
        } else {
            $user = null;
        }

        // 获取当前路由
        $route = [app('http')->getName(), $request->controller(), $request->action()];
        $route = trim(implode('/', $route), '/');

        // 加载不用登陆的路由名单
        $list = array_map('strtolower', require dirname(__DIR__) . '/nologin.php');
        // 当前路由不在白名单则禁止访问
        if (!in_array(strtolower($route), $list)) {
            $request->nologin = false;
            if (!isset($user)) {
                $this->jumpLogin('请先登录');
            }
        } else {
            $request->nologin = true;
        }

        Container::getInstance()->instance('Administrator', $user);

        return $next($request);
    }

    /**
     * 获取用户登录凭证
     * @return array|false
     */
    protected function getAuthToken()
    {
        if (Session::has(self::TokenName)) {
            $token = Session::get(self::TokenName);
        } elseif ($this->request->has(self::TokenName, 'cookie')) {
            $token = $this->request->cookie(self::TokenName);
        } else {
            $token = '';
        }

        $token = explode('@', $token, 2);

        return count($token) == 2 ? $token : false;
    }

    /**
     * 清除用户登录凭证
     */
    static public function clearAuthCookie()
    {
        // 删除SESSION中的uid和sid
        Session::delete(self::TokenName);

        // 删除COOKIE中的token
        Cookie::delete(self::TokenName);
    }

    /**
     * 跳到登录界面
     * @param string $msg 提示消息
     */
    protected function jumpLogin($msg)
    {
        // 清除登录凭证
        $this->clearAuthCookie();

        return Jump::returnResponse()->error($msg, 'Login/index');
    }
}